package gameoflife.gui;

import gameoflife.Pattern;
import gameoflife.RunManager;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

import javax.swing.JFrame;
import javax.swing.WindowConstants;

@SuppressWarnings("serial")
public class Frame extends JFrame {

	private static final Dimension MIN_DIMENSION = new Dimension(400, 350);

	private RunManager runManager;

	public Frame(final RunManager runManager) {
		super();
		this.runManager = runManager;

		setIconImage(Toolkit.getDefaultToolkit().getImage(GameOfLife.class.getResource("icon.png")));
		setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
		setMinimumSize(MIN_DIMENSION);

		final Display display = new Display(runManager.getAutomaton());

		// add components
		setJMenuBar(new MenuBar(this, runManager, display));
		add(display, BorderLayout.CENTER);
		add(StatusBar.createInstance(runManager, display), BorderLayout.PAGE_END);

		// keyboard navigation
		addKeyListener(new KeyAdapter() {
			double velocity = display.getScale() > 0 ? display.getScale() : 1;
			double acceleration = 0.8;
			@Override
			public void keyPressed(KeyEvent e) {
				switch (e.getModifiersEx()) {
				case 0:
					int delta = (int)(velocity += acceleration);
					switch (e.getKeyCode()) {
					case KeyEvent.VK_UP:
						display.pan(0, delta);
						break;
					case KeyEvent.VK_DOWN:
						display.pan(0, -delta);
						break;
					case KeyEvent.VK_RIGHT:
						display.pan(-delta, 0);
						break;
					case KeyEvent.VK_LEFT:
						display.pan(delta, 0);
						break;
					case KeyEvent.VK_EQUALS:
						runManager.speedUp();
						break;
					case KeyEvent.VK_MINUS:
						runManager.speedDown();
						break;
					}
					break;
				case KeyEvent.CTRL_DOWN_MASK:
					switch (e.getKeyCode()) {
					case KeyEvent.VK_UP:
						display.zoom(1);
						break;
					case KeyEvent.VK_DOWN:
						display.zoom(-1);
						break;
					}
					break;
				}
			}
			@Override
			public void keyReleased(KeyEvent e) {
				velocity = display.getScale() > 0 ? display.getScale() : 1;
			}
		});

		// show in center
		pack();
		setLocationRelativeTo(null);
		setVisible(true);
	}

	@Override
	public String getTitle() {
		StringBuilder sb = new StringBuilder("Game of Life");
		Pattern pattern = runManager.getPattern();
		if (pattern != null) {
			sb.append(" - " + pattern.getName());
		}
		return sb.toString();
	}

}
